#include <stdio.h>

#include "./sps_analyze_lib2.h"

/**
 * @brief  lib2H264_get_n_bits() 获取n位数据
 * @note   这里最大可以获取24位数据
 * @param [in]
 * @param [out]
 * @retval 
 */
uint32_t lib2H264_get_n_bits(BITSTREAM_CTL *bs, uint32_t n)
{
    int32_t code = 0;
    uint32_t k_cache = bs->k_cache;// 获取缓存中的数据 —— 最大4个字节
    uint32_t num = bs->b_num;  // 获取缓存中未分析的数据位数 —— 最大32位

    code = k_cache >> (32 - n);       // 获取n位数据
    k_cache <<= n;                    // 去掉已经处理的n位数据
    num -= n;
	printf("[n bits]n=%2d, bs b_num=%02d k_cache=0x%08x code=0x%04x Rdstr=%p Rdcur=%p 0x%02x Rdmax=%p, data_buf=%p data_len=%ld, num=%d (%d-%d)\n",n,
		bs->b_num,bs->k_cache,code, bs->Rdstr,bs->Rdcur,*bs->Rdcur,bs->Rdmax,
		bs->Rdstr - 5,bs->Rdmax-bs->Rdstr,
		num, bs->b_num, n);
    // 注意这里是将右侧的数据也获取过来，所以要判断地址，否则可能会出现越界，越界会将缓冲区外的数据也读进来，
    // 当然，解析参数是对的，但是当缓冲区外的内存被使用的时候，就可能出现蹦溃问题。
    // 这里是判断越界后填充0，或者是直接不再增加数据了
    #if 0
    while (num <= 24)
    {
        k_cache |= (bs->Rdcur < bs->Rdmax?(*bs->Rdcur++):0) << (24 - num);
        num += 8;
    }
    #else
    while ((num <= 24) && (bs->Rdcur < bs->Rdmax))
    {
        k_cache |= *bs->Rdcur++ << (24 - num);
        num += 8;
    }
    #endif
    bs->b_num = num;
    bs->k_cache = k_cache;
	printf("\t      bs b_num=%02d k_cache=0x%08x code=0x%04x Rdstr=%p Rdcur=%p 0x%02x\n",
		bs->b_num, bs->k_cache, code,bs->Rdstr, bs->Rdcur, *bs->Rdcur);
    return code;
}

/**
 * @brief  lib2H264_get_uev() 指数哥伦布解码——获取数据
 * @note   
 * @param [in]
 * @param [out]
 * @retval 
 */
uint32_t lib2H264_get_uev(BITSTREAM_CTL *bs, uint32_t *info)
{
    int32_t i = 0;
    uint32_t len = 0;
    
    uint32_t k_cache = bs->k_cache;
    uint32_t num = bs->b_num;
    
    uint32_t mask = 1u << 31;

    len = 1;
    for (i = 0; (i < 16 && (!(k_cache & mask))); i++, mask >>= 1)
    {
        len++;
    }
    num -= len;
    k_cache <<= len;

    #if 0
    while (num <= 24)
    {
        k_cache |= (bs->Rdcur < bs->Rdmax?(*bs->Rdcur++):0) << (24 - num);
        num += 8;
    }
    #else
    while ((num <= 24) && (bs->Rdcur < bs->Rdmax))
    {
        k_cache |= *bs->Rdcur++ << (24 - num);
        num += 8;
    }
    #endif

    if (len <= 1) // 小于等于1的时候
    {
        *info = 0;
        bs->b_num = num;
        bs->k_cache = k_cache;
        return 1;
    }

    *info = (k_cache >> (32 - (len - 1)));

    num -= len - 1;
    k_cache <<= len - 1;
    #if 0
    while (num <= 24)
    {
        k_cache |= (bs->Rdcur < bs->Rdmax?(*bs->Rdcur++):0) << (24 - num);
        num += 8;
    }
    #else
    while ((num <= 24) && (bs->Rdcur < bs->Rdmax))
    {
        k_cache |= *bs->Rdcur++ << (24 - num);
        num += 8;
    }
    #endif

    bs->b_num = num;
    bs->k_cache = k_cache;
    return (len + len - 1);
}

/**
 * @brief  lib2H264_get_uev_code() 指数哥伦布解码——code num计算
 * @note   
 * @param [in]
 * @param [out]
 * @retval 
 */
uint32_t lib2H264_get_uev_code(BITSTREAM_CTL *bs)
{
    uint32_t len = 0;
    uint32_t inf = 0;

    len = lib2H264_get_uev(bs, &inf);
    return ((1 << (len >> 1)) + inf - 1);
}

/**
 * @brief  lib2H264_read_sev_code() 有符号指数哥伦布编码数据解析
 * @note   
 * @param [in]
 * @param [out]
 * @retval 
 */
uint32_t lib2H264_read_sev_code(BITSTREAM_CTL *bs)
{
    uint32_t k = 0;
    uint32_t code_num = lib2H264_get_uev_code(bs);

    /*lint -e{501}*/
    k = (code_num & 1) ? (code_num + 1) >> 1 : -(uint32_t)(code_num >> 1);

    return k;
}

/**
 * @brief  lib2H264_decode_scaling_list()
 * @note   
 * @param [in]
 * @param [out]
 * @retval 
 */
void lib2H264_decode_scaling_list(BITSTREAM_CTL *bs, int32_t size)
{
    int32_t i = 0;
    int32_t last = 8;
    int32_t next = 8;

    if (!lib2H264_get_1_bits(bs)) /* matrix not written, we use the predicted one */
    {
    }
    else
    {
        for (i = 0; i < size; i++)
        {
            if (next)
            {
                next = (last + lib2H264_read_sev_code(bs)) & 0xff;
            }

            if (!i && !next) /* matrix not written, we use the preset one */
            {
                break;
            }

            last = next ? next : last;
        }
    }
}

/**
 * @brief  lib2H264_decode_scaling_mtx() 
 * @note   if (seq_scaling_matrix_present_flag)那一大坨的解析
 * @param [in]
 * @param [out]
 * @retval 
 */
void lib2H264_decode_scaling_mtx(BITSTREAM_CTL *bs)
{

    if (lib2H264_get_1_bits(bs))
    { 
        lib2H264_decode_scaling_list(bs, 16); /* Intra, Y */
        lib2H264_decode_scaling_list(bs, 16); /* Intra, Cr */
        lib2H264_decode_scaling_list(bs, 16); /* Intra, Cb */ 
        lib2H264_decode_scaling_list(bs, 16); /* Inter, Y */
        lib2H264_decode_scaling_list(bs, 16); /* Inter, Cr */
        lib2H264_decode_scaling_list(bs, 16); /* Inter, Cb */
        lib2H264_decode_scaling_list(bs, 64); /* Intra, 8x8 */
        lib2H264_decode_scaling_list(bs, 64); /* Inter, 8x8 */
    }
}

/**
 * @brief  lib2H264_init_bitstream() 初始化解析参数
 * @note   
 * @param [in]
 * @param [out]
 * @retval 
 */
void lib2H264_init_bitstream(BITSTREAM_CTL *bs, uint8_t *buffer, int32_t size)
{
    bs->b_num = 32;
    bs->Rdstr = buffer;

    // b_rack表示码字处理缓存，一共四个字节，32位，这里初始先填充4个字节的数据，方便后面处理
    bs->k_cache = (bs->Rdstr[0] << 24) + (bs->Rdstr[1] << 16) + (bs->Rdstr[2] << 8) + (bs->Rdstr[3]);
    bs->Rdcur = bs->Rdstr + 4;
    bs->Rdmax = bs->Rdstr + size;
	printf("bs b_num=%d k_cache=0x%08x Rdstr=%p Rdcur=%p 0x%02x Rdmax=%p, data_buf=%p data_len=%d\n",
		bs->b_num,bs->k_cache,bs->Rdstr,bs->Rdcur,*bs->Rdcur,bs->Rdmax,
		buffer,size);
}

/**
 * @brief  lib2H264_get_vui_parameters() 解析vui_parameters参数
 * @note   
 * @param [in]
 * @param [out]
 * @retval 
 */
int32_t lib2H264_get_vui_parameters(BITSTREAM_CTL *bs, _vui_parameters_t *vui_data)
{
	vui_data->aspect_ratio_info_present_flag = lib2H264_get_1_bits(bs); /* vui: aspect_ratio_info_present_flag */
	if (vui_data->aspect_ratio_info_present_flag)
    {
        vui_data->aspect_ratio_idc = lib2H264_get_n_bits(bs, 8); /* vui: aspect_ratio_idc */
        if (vui_data->aspect_ratio_idc == 255) /* Extended_SAR */
        {
            vui_data->sar_width = lib2H264_get_n_bits(bs, 16); /* vui: sar_width */
            vui_data->sar_height = lib2H264_get_n_bits(bs, 16); /* vui: sar_height */
        }
    }

	vui_data->overscan_info_present_flag = lib2H264_get_1_bits(bs); /* vui: overscan_info_present_flag */
    if (vui_data->overscan_info_present_flag)
    {
        vui_data->overscan_appropriate_flag = lib2H264_get_1_bits(bs); /* vui: overscan_appropriate_flag */
    }

	vui_data->video_signal_type_present_flag = lib2H264_get_1_bits(bs); /* vui: video_signal_type_present_flag */
    if (vui_data->video_signal_type_present_flag)
    {
        vui_data->video_format = lib2H264_get_n_bits(bs, 3); /* vui: video_format */
        vui_data->video_full_range_flag = lib2H264_get_1_bits(bs); /* vui: video_full_range_flag */

		vui_data->colour_description_present_flag = lib2H264_get_1_bits(bs); /* vui: colour_description_present_flag */
        if (vui_data->colour_description_present_flag)
        {
            vui_data->colour_primaries = lib2H264_get_n_bits(bs, 8); /* vui: colour_primaries */
            vui_data->transfer_characteristics = lib2H264_get_n_bits(bs, 8); /* vui: transfer_characteristics */
            vui_data->matrix_coefficients = lib2H264_get_n_bits(bs, 8); /* vui: matrix_coefficients */
        }
    }

	vui_data->chroma_loc_info_present_flag = lib2H264_get_1_bits(bs); /* vui: chroma_loc_info_present_flag */
    if (vui_data->chroma_loc_info_present_flag)
    {
        vui_data->chroma_sample_loc_type_top_field = lib2H264_get_uev_code(bs); /* vui: chroma_sample_loc_type_top_field */
        vui_data->chroma_sample_loc_type_bottom_field = lib2H264_get_uev_code(bs); /* vui: chroma_sample_loc_type_bottom_field */
    }

	vui_data->timing_info_present_flag = lib2H264_get_1_bits(bs); /* vui: timing_info_present_flag */
    if (vui_data->timing_info_present_flag)
    {
        /* lib2H264_get_n_bits 不支持取超过24位，因此分两次取，每次取16位 */
		vui_data->num_units_in_tick = lib2H264_get_n_bits(bs, 16) << 16; /* vui: num_units_in_tick */
        vui_data->num_units_in_tick += lib2H264_get_n_bits(bs, 16);
        
        vui_data->time_scale = lib2H264_get_n_bits(bs, 16) << 16; /* vui: time_scale */
        vui_data->time_scale += lib2H264_get_n_bits(bs, 16);

		vui_data->fixed_frame_rate_flag = lib2H264_get_1_bits(bs); /* vui: fixed_frame_rate_flag */
    }
    //后面还有一些数据未解析
    return 1;
}

/**
 * @brief  lib2H264_InterpretSPS() 解析SPS帧信息
 * @note   
 * @param [in]
 * @param [out]
 * @retval 成功返回1，失败返回0
 */
int32_t lib2H264_InterpretSPS(BITSTREAM_CTL *bs, _seq_parameter_set_data_t *sps_data)
{
    int32_t i = 0;
    int32_t profile_idc = 0;
    int32_t hr = 0;
	
    sps_data->profile_idc = lib2H264_get_n_bits(bs, 8);/* profile_idc */
    profile_idc = sps_data->profile_idc;
    if ((profile_idc != BASELINE) && (profile_idc != MAIN)
        && (profile_idc != EXTENDED) && (profile_idc != FREXT_HP)
        && (profile_idc != FREXT_Hi10P) && (profile_idc != FREXT_Hi422)
        && (profile_idc != FREXT_Hi444) && (profile_idc != FREXT_CAVLC444))
    {
        printf("unsupported profile_idc!profile_idc=%d\n", profile_idc);
        return 0;
    }

    sps_data->constraint_set0_flag = lib2H264_get_1_bits(bs); /* sps: constrained_set0_flag */
	sps_data->constraint_set1_flag = lib2H264_get_1_bits(bs); /* sps: constrained_set1_flag */
	sps_data->constraint_set2_flag = lib2H264_get_1_bits(bs); /* sps: constrained_set2_flag */
	sps_data->constraint_set3_flag = lib2H264_get_1_bits(bs); /* sps: constrained_set3_flag */
	sps_data->reserved_zero_4bits  = lib2H264_get_n_bits(bs, 4);/* sps: constraint_set4_flag constraint_set5_flag reserved_zero_2bits*/
	CHECK_PARAM(sps_data->reserved_zero_4bits, 0); /* 必须是全为0 */

    sps_data->level_idc = lib2H264_get_n_bits(bs, 8); /* level_idc */
    sps_data->seq_parameter_set_id = lib2H264_get_uev_code(bs); /* sps: seq_parameter_set_id */
    if ((profile_idc == FREXT_HP) || (profile_idc == FREXT_Hi10P)
        || (profile_idc == FREXT_Hi422) || (profile_idc == FREXT_Hi444) 
        || (profile_idc == FREXT_CAVLC444))
    {
        sps_data->chroma_format_idc       = lib2H264_get_uev_code(bs);  /* sps: chroma_format_idc */
        if(sps_data->chroma_format_idc == 3)
        {
            sps_data->separate_colour_plane_flag = lib2H264_get_1_bits(bs);
        }
		sps_data->bit_depth_luma_minus8   = lib2H264_get_uev_code(bs);  /* sps: bit_depth_luma_minus8 */
		sps_data->bit_depth_chroma_minus8 = lib2H264_get_uev_code(bs);  /* sps: bit_depth_chroma_minus8 */
        sps_data->qpprime_y_zero_transform_bypass_flag = lib2H264_get_1_bits(bs); /* sps: qpprime_y_zero_transform_bypass_flag */
		
		lib2H264_decode_scaling_mtx(bs);
    }
	sps_data->log2_max_frame_num_minus4 = lib2H264_get_uev_code(bs); /* sps: log2_max_frame_num_minus4 */
	sps_data->pic_order_cnt_type = lib2H264_get_uev_code(bs); /* sps: pic_order_cnt_type */
	if (sps_data->pic_order_cnt_type == 0)
    {
        sps_data->log2_max_pic_order_cnt_lsb_minus4 = lib2H264_get_uev_code(bs); /* sps: log2_max_pic_order_cnt_lsb_minus4 */
    }
    else if (sps_data->pic_order_cnt_type == 1)
    {
        sps_data->delta_pic_order_always_zero_flag = lib2H264_get_1_bits(bs);  /* sps: delta_pic_order_always_zero_flag */
        sps_data->offset_for_non_ref_pic = lib2H264_read_sev_code(bs);         /* sps: offset_for_non_ref_pic */
        sps_data->offset_for_top_to_bottom_field = lib2H264_read_sev_code(bs); /* sps: offset_for_top_to_bottom_field */

        sps_data->num_ref_frames_in_pic_order_cnt_cycle = lib2H264_get_uev_code(bs);
        if (sps_data->num_ref_frames_in_pic_order_cnt_cycle > 128)
        {
            return 0;
        }

        for (i = 0; i < sps_data->num_ref_frames_in_pic_order_cnt_cycle; i++)
        {
            sps_data->offset_for_ref_frame_array[i] = lib2H264_read_sev_code(bs); /* sps: offset_for_ref_frame[i] */
        }
    }
    else if (sps_data->pic_order_cnt_type != 2)
    {
        printf(" invalid  pic_order_cnt_type %d\n", sps_data->pic_order_cnt_type);
        return 0;
    }
	sps_data->num_ref_frames = lib2H264_get_uev_code(bs);
	sps_data->gaps_in_frame_num_value_allowed_flag = lib2H264_get_1_bits(bs);  /* sps: gaps_in_frame_num_value_allowed_flag, 有时码流设成0，用来容错处琿*/

    sps_data->pic_width_in_mbs_minus1 = lib2H264_get_uev_code(bs);        /* sps: pic_width_in_mbs_minus1 */
	sps_data->pic_height_in_map_units_minus1 = lib2H264_get_uev_code(bs); /* sps: pic_height_in_map_units_minus1 */
	sps_data->frame_mbs_only_flag = lib2H264_get_1_bits(bs); /* sps: frame_mbs_only_flag */
	if (!sps_data->frame_mbs_only_flag)
    {
        sps_data->mb_adaptive_frame_field_flag = lib2H264_get_1_bits(bs); /* mb_adaptive_frame_field_flag */
    }

	sps_data->direct_8x8_inference_flag = lib2H264_get_1_bits(bs); /* sps: direct_8x8_inference_flag */
    sps_data->frame_cropping_flag = lib2H264_get_1_bits(bs); /* sps: frame_cropping_flag */
	if (sps_data->frame_cropping_flag)
    {
        sps_data->frame_crop_left_offset = lib2H264_get_uev_code(bs);
        sps_data->frame_crop_right_offset = lib2H264_get_uev_code(bs);
        sps_data->frame_crop_top_offset = lib2H264_get_uev_code(bs);
        sps_data->frame_crop_bottom_offset = lib2H264_get_uev_code(bs);
    }

	sps_data->vui_parameters_present_flag = lib2H264_get_1_bits(bs); /* sps: vui_parameters_present_flag */
	if (sps_data->vui_parameters_present_flag)
    {
        hr = lib2H264_get_vui_parameters(bs, &sps_data->vui_parameters);
        if (hr != 1)
        {
            return hr;
        }
    }

    return 1;
}

/**
 * @brief  lib2H264_get_sps_info()
 * @note   
 * @param [in]
 * @param [out]
 * @retval 成功返回1，失败返回0
 */
int32_t lib2H264_get_sps_info(uint8_t *buffer, uint32_t length, _seq_parameter_set_data_t *sps_data)
{
    BITSTREAM_CTL bitstream = {0};
    BITSTREAM_CTL *bs = &bitstream;

    // 前面5个字节是start code 四个字节 + SPS帧类型1个字节
    lib2H264_init_bitstream(bs, buffer + 5, length -5);
    if (!lib2H264_InterpretSPS(bs, sps_data))
    {
        return 0;
    }

    return 1;
}

// calculation width height and framerate
int32_t lib2H264_get_width(_seq_parameter_set_data_t *sps_data)
{
    return (sps_data->pic_width_in_mbs_minus1 + 1) * 16;
}

int32_t lib2H264_get_height(_seq_parameter_set_data_t *sps_data)
{
    return (sps_data->pic_height_in_map_units_minus1 + 1) * 16 * (2 - sps_data->frame_mbs_only_flag);
}

int32_t lib2H264_get_framerate(float *framerate, _seq_parameter_set_data_t *sps_data)
{
    if(sps_data->vui_parameters.timing_info_present_flag)
    {
        if(sps_data->vui_parameters.num_units_in_tick > 0)
        {
            *framerate = (float)sps_data->vui_parameters.time_scale / (float)sps_data->vui_parameters.num_units_in_tick / 2.0;
        }
        else
        {
            *framerate = 25.0;
        }
    }

    return 1;
}
#if 0

/**
 * @brief  lib2H264_sps_info_print() 打印解析出来的SPS信息
 * @note   
 * @param [in]
 * @param [out]
 * @retval 
 */
static void lib2H264_sps_info_print(_seq_parameter_set_data_t* sps_data)
{
    if(NULL != sps_data)
    {
        printf("profile_idc: %d\n", sps_data->profile_idc);    
        printf("constraint_set0_flag: %d\n", sps_data->constraint_set0_flag); 
        printf("constraint_set1_flag: %d\n", sps_data->constraint_set1_flag); 
        printf("constraint_set2_flag: %d\n", sps_data->constraint_set2_flag); 
        printf("constraint_set3_flag: %d\n", sps_data->constraint_set3_flag); 
        printf("reserved_zero_4bits: %d\n", sps_data->reserved_zero_4bits);
        printf("level_idc: %d\n", sps_data->level_idc); 
        printf("seq_parameter_set_id: %d\n", sps_data->seq_parameter_set_id); 
        printf("chroma_format_idc: %d\n", sps_data->chroma_format_idc);
        printf("separate_colour_plane_flag: %d\n", sps_data->separate_colour_plane_flag); 
        printf("bit_depth_luma_minus8: %d\n", sps_data->bit_depth_luma_minus8);    
        printf("bit_depth_chroma_minus8: %d\n", sps_data->bit_depth_chroma_minus8); 
        printf("qpprime_y_zero_transform_bypass_flag: %d\n", sps_data->qpprime_y_zero_transform_bypass_flag); 
        printf("seq_scaling_matrix_present_flag: %d\n", sps_data->seq_scaling_matrix_present_flag); 
        //printf("seq_scaling_list_present_flag:%d\n", sps_data->seq_scaling_list_present_flag); 
        printf("log2_max_frame_num_minus4: %d\n", sps_data->log2_max_frame_num_minus4);
        printf("pic_order_cnt_type: %d\n", sps_data->pic_order_cnt_type);
        printf("num_ref_frames: %d\n", sps_data->num_ref_frames);
        printf("gaps_in_frame_num_value_allowed_flag: %d\n", sps_data->gaps_in_frame_num_value_allowed_flag);
        printf("pic_width_in_mbs_minus1: %d\n", sps_data->pic_width_in_mbs_minus1);
        printf("pic_height_in_map_units_minus1: %d\n", sps_data->pic_height_in_map_units_minus1); 
        printf("frame_mbs_only_flag: %d\n", sps_data->frame_mbs_only_flag);
        printf("mb_adaptive_frame_field_flag: %d\n", sps_data->mb_adaptive_frame_field_flag);
        printf("direct_8x8_inference_flag: %d\n", sps_data->direct_8x8_inference_flag);
        printf("frame_cropping_flag: %d\n", sps_data->frame_cropping_flag);
        printf("frame_crop_left_offset: %d\n", sps_data->frame_crop_left_offset);
        printf("frame_crop_right_offset: %d\n", sps_data->frame_crop_right_offset);
        printf("frame_crop_top_offset: %d\n", sps_data->frame_crop_top_offset);
        printf("frame_crop_bottom_offset: %d\n", sps_data->frame_crop_bottom_offset);    
        printf("vui_parameters_present_flag: %d\n", sps_data->vui_parameters_present_flag);

        if(sps_data->vui_parameters_present_flag)
        {
            printf("aspect_ratio_info_present_flag: %d\n", sps_data->vui_parameters.aspect_ratio_info_present_flag);
            printf("aspect_ratio_idc: %d\n", sps_data->vui_parameters.aspect_ratio_idc);
            printf("sar_width: %d\n", sps_data->vui_parameters.sar_width);
            printf("sar_height: %d\n", sps_data->vui_parameters.sar_height);
            printf("overscan_info_present_flag: %d\n", sps_data->vui_parameters.overscan_info_present_flag);
            printf("overscan_info_appropriate_flag: %d\n", sps_data->vui_parameters.overscan_appropriate_flag);
            printf("video_signal_type_present_flag: %d\n", sps_data->vui_parameters.video_signal_type_present_flag);
            printf("video_format: %d\n", sps_data->vui_parameters.video_format);
            printf("video_full_range_flag: %d\n", sps_data->vui_parameters.video_full_range_flag);
            printf("colour_description_present_flag: %d\n", sps_data->vui_parameters.colour_description_present_flag);
            printf("colour_primaries: %d\n", sps_data->vui_parameters.colour_primaries);
            printf("transfer_characteristics: %d\n", sps_data->vui_parameters.transfer_characteristics);
            printf("matrix_coefficients: %d\n", sps_data->vui_parameters.matrix_coefficients);
            printf("chroma_loc_info_present_flag: %d\n", sps_data->vui_parameters.chroma_loc_info_present_flag);
            printf("chroma_sample_loc_type_top_field: %d\n", sps_data->vui_parameters.chroma_sample_loc_type_top_field);
            printf("chroma_sample_loc_type_bottom_field: %d\n", sps_data->vui_parameters.chroma_sample_loc_type_bottom_field);
            printf("timing_info_present_flag: %d\n", sps_data->vui_parameters.timing_info_present_flag);
            printf("num_units_in_tick: %d\n", sps_data->vui_parameters.num_units_in_tick);
            printf("time_scale: %d\n", sps_data->vui_parameters.time_scale);
            printf("fixed_frame_rate_flag: %d\n", sps_data->vui_parameters.fixed_frame_rate_flag);
            printf("nal_hrd_parameters_present_flag: %d\n", sps_data->vui_parameters.nal_hrd_parameters_present_flag);
            printf("cpb_cnt_minus1: %d\n", sps_data->vui_parameters.nal_hrd_parameters.cpb_cnt_minus1);
            printf("bit_rate_scale: %d\n", sps_data->vui_parameters.nal_hrd_parameters.bit_rate_scale);
            printf("cpb_size_scale: %d\n", sps_data->vui_parameters.nal_hrd_parameters.cpb_size_scale);
            printf("initial_cpb_removal_delay_length_minus1: %d\n", sps_data->vui_parameters.nal_hrd_parameters.initial_cpb_removal_delay_length_minus1);
            printf("cpb_removal_delay_length_minus1: %d\n", sps_data->vui_parameters.nal_hrd_parameters.cpb_removal_delay_length_minus1);
            printf("dpb_output_delay_length_minus1: %d\n", sps_data->vui_parameters.nal_hrd_parameters.dpb_output_delay_length_minus1);
            printf("time_offset_length: %d\n", sps_data->vui_parameters.nal_hrd_parameters.time_offset_length);
            printf("vcl_hrd_parameters_present_flag: %d\n", sps_data->vui_parameters.vcl_hrd_parameters_present_flag);
            printf("low_delay_hrd_flag: %d\n", sps_data->vui_parameters.low_delay_hrd_flag);
            printf("pic_struct_present_flag: %d\n", sps_data->vui_parameters.pic_struct_present_flag);
            printf("bitstream_restriction_flag: %d\n", sps_data->vui_parameters.bitstream_restriction_flag);
            printf("motion_vectors_over_pic_boundaries_flag: %d\n", sps_data->vui_parameters.motion_vectors_over_pic_boundaries_flag);
            printf("max_bytes_per_pic_denom: %d\n", sps_data->vui_parameters.max_bytes_per_pic_denom);
            printf("max_bits_per_mb_denom: %d\n", sps_data->vui_parameters.max_bits_per_mb_denom);
            printf("log2_max_mv_length_horizontal: %d\n", sps_data->vui_parameters.log2_max_mv_length_horizontal);
            printf("log2_max_mv_length_vertical: %d\n", sps_data->vui_parameters.log2_max_mv_length_vertical);
            printf("num_reorder_frames: %d\n", sps_data->vui_parameters.num_reorder_frames);
            printf("max_dec_frame_buffering: %d\n", sps_data->vui_parameters.max_dec_frame_buffering);
        }
        
    }
}
#endif
int sps_analyze_lib2_demo(int argc, const char *argv[]) 
{
	int32_t i = 0;
    int32_t data_len = 0;
    uint8_t data_buffer[] = {0x00,0x00,0x00,0x01,0x67,0x64,0x00,0x33,0xac,0x15,0x14,0xa0,0x50,0x05,0xba,0x68,0x80,0x00,0x01,0xf4,0x00,0x00,0x75,0x30,0x02 };
    VIDEO_ES_INFO esInfo = {0};
	VIDEO_ES_INFO *pEsInfo = &esInfo;
	_seq_parameter_set_data_t sps_info = {0};
    data_len = sizeof(data_buffer)/sizeof(data_buffer[0]);
	printf("data_buffer size is %d\n", data_len);
	for(i = 0;i < data_len; i++)
	{
		printf("addr=%p data_buffer[%d]=0x%02x \n", &data_buffer[i], i, data_buffer[i]);
	}
    printf("\n");
	
	lib2H264_get_sps_info(data_buffer, data_len, &sps_info);
    pEsInfo->width = lib2H264_get_width(&sps_info);
    pEsInfo->height = lib2H264_get_height(&sps_info);
    lib2H264_get_framerate(&pEsInfo->frame_rate, &sps_info);
	printf("pEsInfo w=%d h=%d rate=%f\n", pEsInfo->width, pEsInfo->height, pEsInfo->frame_rate);

    //lib2H264_sps_info_print(&sps_info);
    return 0;
}
